package com.cn.removewatermark.batchdownload;



import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cn.removewatermark.domain.MyProgress;
import com.cn.removewatermark.parsingurl.ParsingURLs;
import com.cn.removewatermark.utils.JsonUtils;
import com.sun.javafx.css.PseudoClassState;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/*
*批量下载快手视频视频
* */
public class BatchDownload {

    public final static Map<String,String> header=new HashMap<>();
    private static volatile ParsingURLs parsingURLs=null;
    private  static final ConcurrentHashMap<String,MyProgress> replicaVariable=new ConcurrentHashMap<>();

    public  static  CountDownLatch countDownLatch=null;

    public static ConcurrentHashMap<String,MyProgress> getConcurrentHashMap(){
        return replicaVariable;
    }
    public static MyProgress getReplicaVariable(String key){
        return replicaVariable.get(key);
    }

    public static void add(String key,MyProgress progress){
        replicaVariable.put(key,progress);
    }

    /*
    * 保障ParsingURLs的单列
    * */
    static {
        if (Objects.isNull(parsingURLs)){
            synchronized (ParsingURLs.class){
                if (Objects.isNull(parsingURLs))parsingURLs=new ParsingURLs();
                String date = new Date().toString().replace(":", "_").replace(" ","");
                if (!Files.exists(Paths.get(DownloadThead.path+date))) {
                    try {
                        DownloadThead.date=date;
                        Files.createDirectories(Paths.get(DownloadThead.path+date));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }

        }
    }


    /*
    * 开始下载
    * */
    public void start(String userId){
        String pre="https://www.kuaishou.com/graphql";
        String pcursor="";
        Download download=new Download();
        int works = works(pre, userId);//获取爬取的主页作品数量

        if (works<=0){
            return;
        }

        countDownLatch=new CountDownLatch(works);

        try {
            while (true){
                System.out.println(pcursor);
                HttpRequest request = createRequest(pre,userId,pcursor);
                String json = request.execute().body();
                pcursor = JsonUtils.parsingJSON(json,"pcursor");

                List<String> videoUrl = parsingJsonToVideoUrlList(json);
                System.out.println("videoUrl======="+videoUrl.size());
                videoUrl.forEach(item->{
                    try {
                        download.putMessage(item);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });

                if (pcursor == null || pcursor.equals("no_more")) {
                    System.out.println("pcursor=========="+pcursor);
                    System.out.println("no_more");
                    Download.setEndFlag(new AtomicBoolean(true));//结束标志
                    break;
                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /*
    * 获得主页作品数量
    * */
    public int works(String url,String userId){
        Map<String,String> worksHeader=new HashMap<>();
        worksHeader.put("Origin","https://www.kuaishou.com");
        worksHeader.put("Referer","https://www.kuaishou.com/profile/"+userId);
        worksHeader.put("User-Agent",ParsingURLs.properties.get("Windows").toString());
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("operationName","visionProfile");
        jsonObject.put("query",ParsingURLs.properties.get("worksJquery"));
        JSONObject jsonObject1=new JSONObject();
        jsonObject1.put("userId",userId);
        jsonObject.put("variables",jsonObject1);
        String json = HttpUtil.createPost(url)
                .addHeaders(worksHeader)
                .contentType("application/json")
                .body(jsonObject.toString())
                .cookie(ParsingURLs.properties.get("cookie").toString()).execute().body();
        String userProfile = JsonUtils.parsingJSON(json, "userProfile");
        return Integer.parseInt(JSONUtil.parseObj(JSONUtil.parseObj(userProfile).get("ownerCount")).get("photo_public").toString());

    }

    /*
    * 对于请求进行设置
    * */
    private HttpRequest createRequest(String url,String userId,String pcursor){
        header.put("Accept","*/*");
        header.put("Origin","https://www.kuaishou.com");
        header.put("Referer","https://www.kuaishou.com/profile/"+userId);
        JSONObject obj = JSONUtil.createObj();
        obj.put("operationName","visionProfilePhotoList");
        obj.put("query",ParsingURLs.properties.get("query"));
        JSONObject obj1 = JSONUtil.createObj();
        obj1.put("userId",userId);
        obj1.put("pcursor",pcursor);
        obj1.put("page","profile");
        obj.put("variables",obj1);
        return HttpUtil.createPost(url)
                .addHeaders(header)
                .body(obj.toString())
                .contentType("application/json")
                .cookie(ParsingURLs.properties.get("cookie").toString());
    }


    /*
    * 解析获取的json数据获得视频下载地址的集合
    * */
    private List<String> parsingJsonToVideoUrlList(String json){
       return JSONUtil.parseArray(JsonUtils.parsingJSON(json, "feeds"))
                .stream()
                .map(item->{
                    JSONObject jsonObject= (JSONObject)item;
                    String videoResource = JSONUtil.parseObj(jsonObject.get("photo").toString()).get("videoResource").toString();
                    String h264 = JSONUtil.parseObj(videoResource).get("h264").toString();
                    String adaptationSet = JSONUtil.parseObj(h264).get("adaptationSet").toString();
                    String index = JSONUtil.parseArray(adaptationSet).get(0).toString();
                    String representation = JSONUtil.parseObj(index).get("representation").toString();
                    String representationIndex = JSONUtil.parseArray(representation).get(0).toString();
                    return JSONUtil.parseObj(representationIndex).get("url").toString();
                }).collect(Collectors.toList());

    }

}
